#ifndef __STEPPERMOTOR_H
#define __STEPPERMOTOR_H

#include "stm32f10x.h"

#define M1_CLOCKWISE					0
#define M1_UNCLOCKWISE				1
#define M2_CLOCKWISE					0
#define M2_UNCLOCKWISE				1
#define M3_CLOCKWISE					0
#define M3_UNCLOCKWISE				1
#define M4_CLOCKWISE					0
#define M4_UNCLOCKWISE				1

#define M1DIV               32                          //定义电机1的细分数
#define M2DIV               32                          //定义电机2的细分数
#define M3DIV               32                          //定义电机3的细分数
#define M4DIV               32   //定义电机4的细分数

#define M_FRE_START					8000 //电机的启动频率
#define M_FRE_AA						4500	//电机频率的加加速度
#define M_T_AA							2			//电机频率的加加速时间
#define M_T_UA							6     //电机频率的匀加速时间
#define M_T_RA							2		  //电机频率的减加速时间 

#define F2TIME_PARA				  12000000   									//将频率值转换为定时器寄存器值得转换参数
#define STEP_PARA					  10	   											//任意时刻转动步数修正因子
#define STEP_AA						  31       										//加加速阶段，离散化点数
#define STEP_UA						  31			  									//匀加速阶段，离散化点数
#define STEP_RA						  31													//减加速阶段，离散化点数

// 定义定时器周期，输出比较模式周期设置为0xFFFF
#define STEPMOTOR_TIM_PERIOD                  0xFFFF

#define AXIS_X                                0   // 各轴标号
#define AXIS_Y                                1

#define iabs(x)  (x)>0?(x):-(x)

/* 类型定义 ------------------------------------------------------------------*/
// 步进电机控制器类型定义
typedef struct{
  uint16_t  Pulse_Pin ; 	    // 定时器脉冲输出引脚
  uint32_t  Pulse_Channel;		// 定时器脉冲输出通道
  uint16_t  Ena_Pin ;         // 电机使能引脚编号
  uint16_t  Dir_Pin ;         // 电机方向引脚编号
  GPIO_TypeDef *Dir_Port;     // 电机方向引脚端口
  GPIO_TypeDef *Ena_Port;     // 电机使能引脚端口
}StepMotor_CtrlTypedef;

// 插补算法类型定义
typedef struct {
  __IO uint8_t  X_Dir;        // X轴方向
  __IO uint8_t  Y_Dir;        // Y轴方向
  __IO int32_t  END_X;		 	  // 终点坐标X
	__IO int32_t  END_Y;		 	  // 终点坐标Y
	__IO uint32_t END_Pulse;	  // 终点位置总的脉冲数
	__IO uint32_t Active_Axis;  // 活动轴
	__IO int32_t  F_e;			 	  // 函数方程
}Interpolation_Typedef;

typedef struct
{
  uint8_t en;	          //使能
  uint8_t dir;			  		//方向
  uint8_t running;		  		//转动完成标志 
  uint8_t rstflg;		  	//复位标志
  uint8_t divnum;		  	//分频数
  uint8_t speedenbale;		//是否使能速度控制	
  uint8_t clockwise;			//顺时针方向对应的值
  uint8_t id;					//电机id

  uint32_t pulsecount;
  uint16_t *Counter_Table;  		//指向启动时，时间基数计数表
  uint16_t *Step_Table;  			//指向启动时，每个频率脉冲个数表
  uint16_t CurrentIndex;    	//当前表的位置
  uint16_t TargetIndex;    	//目标速度在表中位置
  uint16_t StartTableLength;   //启动数据表
  uint16_t StopTableLength;    //启动数据表
  uint32_t StartSteps;					//电机启动步数
  uint32_t StopSteps;					//电机停止步数
  uint32_t RevetDot;			  		//电机运动的减速点
  uint32_t PulsesGiven;			  //电机运动的总步数
  uint32_t PulsesHaven;				//电机已经运行的步数
  uint32_t CurrentPosition;		//当前位置
  uint32_t MaxPosition;				//最大位置，超过该位置置0
  uint32_t CurrentPosition_Pulse;		//当前位置
  uint32_t MaxPosition_Pulse;		//当前位置
  unsigned long long Time_Cost_Act;	//实际运转花费的时间
  unsigned long long Time_Cost_Cal;	//计算预估运转花费的时间
  TIM_TypeDef* TIMx;	
}MOTOR_CONTROL_S;

extern uint16_t Motor1TimeTable[2*(STEP_AA+STEP_UA+STEP_RA)+1];
extern uint16_t Motor1StepTable[2*(STEP_AA+STEP_UA+STEP_RA)+1];
extern uint16_t Motor2TimeTable[2*(STEP_AA+STEP_UA+STEP_RA)+1];
extern uint16_t Motor2StepTable[2*(STEP_AA+STEP_UA+STEP_RA)+1];
extern uint16_t Motor3TimeTable[2*(STEP_AA+STEP_UA+STEP_RA)+1];
extern uint16_t Motor3StepTable[2*(STEP_AA+STEP_UA+STEP_RA)+1];
extern uint16_t Motor4TimeTable[2*(STEP_AA+STEP_UA+STEP_RA)+1];
extern uint16_t Motor4StepTable[2*(STEP_AA+STEP_UA+STEP_RA)+1];

extern MOTOR_CONTROL_S motor1;
extern MOTOR_CONTROL_S motor2;
extern MOTOR_CONTROL_S motor3;
extern MOTOR_CONTROL_S motor4;

void MotorRunParaInitial(void);
void CalcMotorPeriStep_CPF(float fstart,float faa,float taa,float tua,float tra,uint16_t MotorTimeTable[],uint16_t MotorStepTable[]);
float GetFreAtTime(float fstart,float faa,float taa,float tua,float tra,float t);
void Initial_Motor(unsigned char MotorID, unsigned char StepDive,unsigned int maxposition);
void Start_Motor_S(unsigned char MotorID,unsigned char dir,unsigned int Degree);
void Motor_Reinitial(unsigned char MotorID);
unsigned long long Get_TimeCost_ReverDot_S(unsigned char MotorID);
void TIMX_UP_IRQHandler_S(MOTOR_CONTROL_S* pmotor);
void Arc_IncMoveCW(int32_t Xe,int32_t Ye,int32_t coordsA,int32_t coordsB,uint32_t Speed);
void TIMX_UP_IRQHandler_Arc(void);

#endif /* __STEPPERMOTOR_H */